/*
 * SHOPTNT 版权所有。
 * 未经许可，您不得使用此文件。
 * 官方地址：www.shoptnt.cn
 */
package cn.shoptnt.consumer.shop.trade.consumer;

import cn.shoptnt.client.payment.PayLogClient;
import cn.shoptnt.client.promotion.CouponClient;
import cn.shoptnt.client.promotion.FullDiscountGiftClient;
import cn.shoptnt.client.trade.OrderMetaClient;
import cn.shoptnt.consumer.core.event.TradeIntoDbEvent;
import cn.shoptnt.framework.sncreator.SnCreator;
import cn.shoptnt.framework.util.JsonUtil;
import cn.shoptnt.framework.util.StringUtil;
import cn.shoptnt.model.base.SubCode;
import cn.shoptnt.model.promotion.coupon.dos.CouponDO;
import cn.shoptnt.model.promotion.coupon.vo.GoodsCouponPrice;
import cn.shoptnt.model.promotion.tool.vo.GiveGiftVO;
import cn.shoptnt.model.trade.order.dos.OrderMetaDO;
import cn.shoptnt.model.trade.order.dos.PayLog;
import cn.shoptnt.model.trade.order.dto.OrderDTO;
import cn.shoptnt.model.trade.order.enums.OrderMetaKeyEnum;
import cn.shoptnt.model.trade.order.enums.OrderServiceStatusEnum;
import cn.shoptnt.model.trade.order.enums.PayStatusEnum;
import cn.shoptnt.model.trade.order.vo.TradeVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 订单其他信息入库
 *
 * @author Snow create in 2018/6/26
 * @version v2.0
 * @since v7.0.0
 */
@Component
@Order(1)
public class OrderMetaConsumer implements TradeIntoDbEvent {


    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OrderMetaClient orderMetaClient;


    @Autowired
    SnCreator snCreator;

    @Autowired
    private FullDiscountGiftClient fullDiscountGiftClient;

    @Autowired
    private CouponClient couponClient;

    @Autowired
    private PayLogClient payLogClient;

    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void onTradeIntoDb(TradeVO tradeVO) {

        List<OrderDTO> orderList = tradeVO.getOrderList();
        //获取使用的优惠券，根据商家匹配到相应商家中
        for (OrderDTO orderDTO : orderList) {
            addCashBack(orderDTO);
            addUsePoint(orderDTO);
            addGiftPoint(orderDTO);
            addGiftCoupon(orderDTO);
            addCouponPrice(orderDTO);
            //赠品入库改为订单变更（OrderGiftStoreConsumer）的消息中进行，否则会先扣减赠品库存再入库赠品
//            addGift(orderDTO);
            addLog(orderDTO);
            addFullMinusPrice(orderDTO);
            addMinusPrice(orderDTO);
        }

    }



    /**
     * 记录返现金额
     *
     * @param orderDTO
     */
    private void addCashBack(OrderDTO orderDTO) {
        try {
            //记录返现金额
            double cashBack = orderDTO.getPrice().getCashBack();
            OrderMetaDO cashBackMeta = new OrderMetaDO();
            cashBackMeta.setMetaKey(OrderMetaKeyEnum.CASH_BACK.name());
            cashBackMeta.setMetaValue(cashBack + "");
            cashBackMeta.setOrderSn(orderDTO.getSn());
            this.orderMetaClient.add(cashBackMeta);
            logger.debug("返现金额入库完成");
        } catch (Exception e) {
            logger.error("返现金额入库出错", e);
        }

    }


    /**
     * 记录使用的积分
     *
     * @param orderDTO
     */
    private void addUsePoint(OrderDTO orderDTO) {
        try {

            //使用的积分
            Long consumerPoint = orderDTO.getPrice().getExchangePoint();
            if (consumerPoint > 0) {
                //使用积分的记录
                OrderMetaDO pointMeta = new OrderMetaDO();
                pointMeta.setMetaKey(OrderMetaKeyEnum.POINT.name());
                pointMeta.setMetaValue(consumerPoint + "");
                pointMeta.setOrderSn(orderDTO.getSn());
                pointMeta.setStatus(OrderServiceStatusEnum.NOT_APPLY.name());
                this.orderMetaClient.add(pointMeta);
            }

            logger.debug("记录使用的积分");

        } catch (Exception e) {
            logger.error("记录使用的积分出错", e);
        }

    }


    /**
     * 赠送积分的记录
     *
     * @param orderDTO
     */
    private void addGiftPoint(OrderDTO orderDTO) {
        try {
            if(StringUtil.isEmpty(orderDTO.getGiftJson())){
                return;
            }
            //赠品入库
            List<GiveGiftVO> giftList= JsonUtil.jsonToList(orderDTO.getGiftJson(), GiveGiftVO.class);
            Integer givePoint = 0;
            for (GiveGiftVO giveGiftVO:giftList) {
                if("point".equals(giveGiftVO.getType())){
                    givePoint += (Integer)giveGiftVO.getValue();
                }
            }
            //赠送积分的记录
            OrderMetaDO giftPointMeta = new OrderMetaDO();
            giftPointMeta.setMetaKey(OrderMetaKeyEnum.GIFT_POINT.name());
            giftPointMeta.setMetaValue(givePoint + "");
            giftPointMeta.setOrderSn(orderDTO.getSn());
            giftPointMeta.setStatus(OrderServiceStatusEnum.NOT_APPLY.name());
            this.orderMetaClient.add(giftPointMeta);

            logger.debug("赠送积分完成");
        } catch (Exception e) {
            logger.error("赠送积分的记录出错", e);
        }

    }


    /**
     * 赠品入库
     *
     * @param orderDTO
     */
    private void addGiftCoupon(OrderDTO orderDTO) {
        try {
            if(StringUtil.isEmpty(orderDTO.getGiftJson())){
                return;
            }
            //赠品入库
            List<GiveGiftVO> giftList= JsonUtil.jsonToList(orderDTO.getGiftJson(), GiveGiftVO.class);
            List<CouponDO> couponList = new ArrayList<>();
            for (GiveGiftVO giveGiftVO:giftList) {
                if("coupon".equals(giveGiftVO.getType())){
                    couponList.add(couponClient.getModel(Long.valueOf(giveGiftVO.getValue().toString())));
                }
            }

            OrderMetaDO couponMeta = new OrderMetaDO();
            couponMeta.setMetaKey(OrderMetaKeyEnum.COUPON.name());
            couponMeta.setMetaValue(JsonUtil.objectToJson(couponList));
            couponMeta.setOrderSn(orderDTO.getSn());
            couponMeta.setStatus(OrderServiceStatusEnum.NOT_APPLY.name());
            this.orderMetaClient.add(couponMeta);

            logger.debug("赠品完成");

        } catch (Exception e) {
            logger.error("赠品出错", e);
        }

    }


    /**
     * 记录使用优惠券的金额
     *
     * @param orderDTO
     */
    private void addCouponPrice(OrderDTO orderDTO) {
        try {
            List<GoodsCouponPrice> couponList = orderDTO.getGoodsCouponPrices();
            //记录使用优惠券的金额
            OrderMetaDO orderMeta = new OrderMetaDO();
            orderMeta.setMetaKey(OrderMetaKeyEnum.COUPON_PRICE.name());
            orderMeta.setMetaValue(JsonUtil.objectToJson(couponList));
            orderMeta.setOrderSn(orderDTO.getSn());
            orderMetaClient.add(orderMeta);

            logger.debug("使用优惠券的金额完成");

        } catch (Exception e) {
            logger.error("使用优惠券的金额出错", e);
        }

    }


    /**
     * 记录满减金额的金额
     *
     * @param orderDTO
     */
    private void addFullMinusPrice(OrderDTO orderDTO) {
        try {

            //记录使用优惠券的金额
            OrderMetaDO orderMeta = new OrderMetaDO();
            orderMeta.setMetaKey(OrderMetaKeyEnum.FULL_MINUS.name());
            orderMeta.setMetaValue("" + orderDTO.getPrice().getFullMinus());
            orderMeta.setOrderSn(orderDTO.getSn());
            orderMetaClient.add(orderMeta);
            logger.debug("订单满减金额入库完成");
        } catch (Exception e) {
            logger.error("订单满减金额入库出错", e);
        }

    }

    /**
     * 记录单品立减金额（单品立减信息入库）
     *
     * @param orderDTO
     */
    private void addMinusPrice(OrderDTO orderDTO) {
        try {
            Double minusPrice = orderDTO.getPrice().getMinusPrice();
            OrderMetaDO minusPriceMeta = new OrderMetaDO();
            minusPriceMeta.setMetaKey(OrderMetaKeyEnum.MINUS.name());
            minusPriceMeta.setMetaValue(minusPrice + "");
            minusPriceMeta.setOrderSn(orderDTO.getSn());
            this.orderMetaClient.add(minusPriceMeta);
            logger.debug("单品立减入库完成");
        } catch (Exception e) {
            logger.error("单品立减入库失败", e);
        }

    }


    /***
     * 赠品入库
     * @param orderDTO
     */
    private void addGift(OrderDTO orderDTO) {

//        try {
//            if(StringUtil.isEmpty(orderDTO.getGiftJson())){
//                return;
//            }
//
//            //赠品入库
//            List<GiveGiftVO> giftList= JsonUtil.jsonToList(orderDTO.getGiftJson(), GiveGiftVO.class);
//            List<FullDiscountGiftDO> giftLists = new ArrayList<>();
//            for (GiveGiftVO giveGiftVO:giftList) {
//                if("gift".equals(giveGiftVO.getType())){
//                    FullDiscountGiftDO fullDiscountGiftDO = fullDiscountGiftClient.getModel(Long.valueOf(giveGiftVO.getValue().toString()));
//                    //赠品库存大于0，赠送赠品
//                    if(fullDiscountGiftDO != null && fullDiscountGiftDO.getEnableStore() > 0){
//                        giftLists.add(fullDiscountGiftDO);
//                    }
//
//                }
//            }
//            if(giftLists.size() > 0){
//                OrderMetaDO giftMeta = new OrderMetaDO();
//                giftMeta.setMetaKey(OrderMetaKeyEnum.GIFT.name());
//                giftMeta.setMetaValue(JsonUtil.objectToJson(giftLists));
//                giftMeta.setOrderSn(orderDTO.getSn());
//                giftMeta.setStatus(OrderServiceStatusEnum.NOT_APPLY.name());
//                this.orderMetaClient.add(giftMeta);
//            }
//
//            logger.debug("赠品入库完成");
//
//        } catch (Exception e) {
//            logger.error("赠品入库出错", e);
//        }


    }


    /**
     * 记录日志
     *
     * @param orderDTO
     */
    private void addLog(OrderDTO orderDTO) {
        try {
            //付款单
            PayLog payLog = new PayLog();
            payLog.setPayLogSn(""+snCreator.create(SubCode.PAY_BILL));
            payLog.setOrderSn(orderDTO.getSn());
            payLog.setPayMemberName(orderDTO.getMemberName());
            payLog.setPayStatus(PayStatusEnum.PAY_NO.name());
            payLog.setPayWay(orderDTO.getPaymentType());

            this.payLogClient.add(payLog);

            logger.debug("日志入库完成");

        } catch (Exception e) {
            logger.error("日志入库出错", e);
        }

    }

}
